本文的选题依据来自 https://cspiration.com/leetcodeClassification 中的划分,下面的序号以 Leetcode 英文版为准
1.TwoSum
- 不要使用暴力解法,虽然在 LC 上可以 AC,但是已经是极差表现
- 使用 HashMap 进行存储,注意存在重复元素的极端情况,需要在 map 中取元素时考虑是不是当前位置元素,比如 target=6 时,[3,3]的情况
3.Longest Substring Without Repeating Characters
- 该题使用 HashSet 和滑动窗口解决
- HashSet 是为了保证集合中的元素唯一,方便针对重复元素进行移除,若改为 ArrayList 同样可行,不过在 else 中的 list 需要一直 remove 0 号元素,而不是如同 set 中的 remove 当前元素
- 在地址安全范围内,如果当前元素不在 set 中说明是个新元素,那么加入 set,并将 end 后移,计算 max;如果当前元素在 set 中说明已存在,那么从 set 中移除,并将 start 后移
4.Median of Two Sorted Arrays
- 该题使用二分查找和切分的思想
- 在对两个数组的中位数(长度奇数取中间,偶数取中间两数的平均值)进行查找时,最直接的方法是合并数组之后查找,但会超时
- 采用切分的思想,由于两个数组是分别排序好的数组,所以中位数一定出现在两个数组总长度的中间位置,那么我们对数组 1 进行切分,假设数组 1 长度为 4,数组 2 长度为 6,那么当我们将数组 1 切分为长度左 1 右 3 时,数组 2 自然被切分成左 4 右 2,因为只有这样左边和右边才数量相等(总长度为奇数时两边数量差 1),只有在左右数量相等(差 1)的情况下,中位数才可能在切分点周围的数中产生
- 采用二分法对数组 1 进行切分,会出现三种情况
- L1>R2,这说明需要缩小数组 1 的范围;L2>R1,这说明需要缩小数组 2 的范围;正常情况:L1<=R2&&L2<=R1,此时就根据总长度奇偶情况进行区分,当总长度为偶数时就是左边(L1,L2)中的最大值和右边(R1,R2)中的最小值的平均值;当总长度为奇数时就是右边(R1,R2)中的最小值
⭐5.Longest Palindromic Substring
- 该题使用 Manacher 算法应该是最高效的,但是我没看懂,看以后会不会填坑(大概率不会
- 使用动态规划的思想解决问题,首先以字符串长度建立二维数组,然后就开始填表,其中 i 代表开始点,j 代表能到达的最远点。因为 j 代表最远端,自然是对它进行长度遍历,而把 i 限制在 j 的范围内,然后就计算 dp[i][j],它的值为 true 或者 false 和几个因素相关.
- 当 i 和 j 位置的元素不相等时自然不能构成回文,直接 false.
- 当 i 和 j 位置元素相同时分为两种情况。一种是 i 和 j 的差在 2(也就是 i 和 j 之间最多有 3 个元素,当首尾元素相同时,中间那个元素已经无关紧要了,这个子字符串一定是回文);另一种是 i 和 j 包裹之内的元素是不是回文,所以判断下 dp[i+1][j-1]的状态,如果它为 true,则当前的子字符串也是回文,就拿它和 max 进行比较,过程结束。
7.Reverse Integer
- 本题只需要注意溢出问题,其余的都是常规反转数字,x%10 可以每次取数字的最后一位,然后使用 x/=10 减少 x 的大小
8.String to Integer (atoi)
- 该题属于对边界条件考察,主要是要注意开头是否满足条件、溢出处理
10.Regular Expression Matching
- 该题属于动态规划问题,题目意思是给定一个字符串 s,要求判定给出的匹配 p 能否匹配成功,其中 p 中只能存在小写字母、.(代表可以匹配任意单个字符)、*(代表可以匹配零个或者多个前置字符,这里需要注意零个,这意味着*实质上可以扮演删除的角色)这三种情况
- 动态规划的题目还是首先建立二维表,dp[i][j]的意思是 s[0-i]和 p[0-j]是否匹配,这样就存在很多情况
- 如果 s[i]==p[j],那么 dp[i][j] = dp[i-1][j-1]
- 如果 p[j]==’.’,那么 dp[i][j] = dp[i-1][j-1] (因为.可以匹配任何单个字母)
- 如果 p[j]==’*‘,那么还存在两种情况。一种是 p[j-1]!=s[i],那么 dp[i][j] = dp[i][j-2] (因为此时*号起到了删除的作用,此时*号前面的字母已经被删除,所以比较的就不是 j-1 而是 j-2);另一种情况是 p[j-1]==s[i] (此时可以匹配单个或多个相同字母)或者 p[j-1]==’.’,这样的话又分为三种情况 dp[i][j]==dp[i][j-1],此时可以匹配单个字母;dp[i][j]=dp[i-1][j],此时可以匹配多个字母;dp[i][j]=dp[i][j-2],此时匹配空字符。在这三种情况中有一种情况成立即可。
11.Container With Most Water
- 该题意思是给定一个数组,找出这个数组能够组成的最大面积是多少
- 这个通过前后夹击来解决,由于水槽的高度取决于较短的那个边,所以 h=Math.min(l,r),之后就是移动规则,如果 l < r,则要使得 l 变大,所以它右移;否则,r 左移。
12.Integer to Roman
- 该题比较简单,就是将所有的情况列举出来,通过遍历进行添加
13.Roman to Integer
- 这个题目需要注意的一点就是罗马数字的拼接规律是当左边数字小于右边数字时,它的值等于右边-左边,比如 IV=V-I=5-1=4
- 先列举出所有的字母对应数字,然后对每一位进行取值,如果发现当前转化后的数字小于前一个转化后的数字,则用当前数字-2*前一位数字,之所以是 2 倍关系,是因为以…IV 为例,在 V 没有加入讨论之前,这个 I 就已经在上一轮中被加到总和当中去了,但其实它要和 V 组成 IV,所以需要将它减掉之后再计算 IV,也就相当于当前的 V 需要减去两个 I 才是正确数字